<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>动态博客 | 真实API请求</title>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        :root {
            --primary: #2c3e50;
            --secondary: #34495e;
            --accent: #3498db;
            --text: #333;
            --text-light: #777;
            --bg: #f8f9fa;
            --border: #eaeaea;
            --success: #27ae60;
            --error: #e74c3c;
        }

        body {
            font-family: 'Segoe UI', 'Helvetica Neue', sans-serif;
            line-height: 1.6;
            color: var(--text);
            background-color: var(--bg);
            padding: 40px 20px;
            max-width: 800px;
            margin: 0 auto;
            min-height: 100vh;
            display: flex;
            flex-direction: column;
        }

        header {
            text-align: center;
            margin-bottom: 30px;
            padding-bottom: 20px;
            border-bottom: 1px solid var(--border);
            position: relative;
        }

        .logo {
            font-size: 2.8rem;
            color: var(--primary);
            margin-bottom: 15px;
            transition: transform 0.3s ease;
        }

        .logo:hover {
            transform: rotate(15deg);
        }

        .site-title {
            font-size: 1.8rem;
            font-weight: 300;
            letter-spacing: 2px;
            color: var(--primary);
            margin-bottom: 10px;
        }

        .site-subtitle {
            font-size: 1rem;
            color: var(--text-light);
            max-width: 500px;
            margin: 0 auto;
        }

        .article {
            background: white;
            padding: 30px;
            margin-bottom: 25px;
            border-radius: 4px;
            transition: transform 0.3s ease, box-shadow 0.3s ease;
            position: relative;
            opacity: 0;
            transform: translateY(20px);
            animation: fadeIn 0.5s ease forwards;
        }

        @keyframes fadeIn {
            to {
                opacity: 1;
                transform: translateY(0);
            }
        }

        .article:hover {
            transform: translateY(-3px);
            box-shadow: 0 5px 20px rgba(0, 0, 0, 0.05);
        }

        .article-date {
            font-size: 0.85rem;
            color: var(--text-light);
            margin-bottom: 15px;
            display: block;
        }

        .article-title {
            font-size: 1.5rem;
            font-weight: 600;
            margin-bottom: 15px;
            color: var(--primary);
        }

        .article-title a {
            text-decoration: none;
            color: inherit;
            transition: color 0.3s ease;
        }

        .article-title a:hover {
            color: var(--accent);
        }

        .article-excerpt {
            color: var(--text-light);
            margin-bottom: 20px;
            font-size: 1.05rem;
            line-height: 1.7;
        }

        .read-more {
            display: inline-block;
            color: var(--accent);
            text-decoration: none;
            font-size: 0.95rem;
            font-weight: 500;
            position: relative;
            padding-bottom: 3px;
        }

        .read-more::after {
            content: '';
            position: absolute;
            left: 0;
            bottom: 0;
            width: 0;
            height: 1px;
            background-color: var(--accent);
            transition: width 0.3s ease;
        }

        .read-more:hover::after {
            width: 100%;
        }

        .category-tag {
            display: inline-block;
            background: rgba(52, 152, 219, 0.1);
            color: var(--accent);
            padding: 3px 10px;
            border-radius: 12px;
            font-size: 0.8rem;
            margin-top: 15px;
            text-decoration: none;
        }

        footer {
            text-align: center;
            padding: 40px 0;
            color: var(--text-light);
            font-size: 0.9rem;
            border-top: 1px solid var(--border);
            margin-top: auto;
        }

        .pagination {
            display: flex;
            justify-content: center;
            margin: 40px 0;
            flex-wrap: wrap;
            gap: 8px;
        }

        .pagination a {
            display: inline-flex;
            align-items: center;
            justify-content: center;
            width: 36px;
            height: 36px;
            text-decoration: none;
            color: var(--text);
            border-radius: 50%;
            transition: all 0.3s ease;
            font-size: 0.9rem;
        }

        .pagination a:hover,
        .pagination a.active {
            background: var(--accent);
            color: white;
        }

        .pagination .disabled {
            opacity: 0.5;
            cursor: not-allowed;
        }

        #article-container {
            min-height: 300px;
            position: relative;
        }

        .loading {
            text-align: center;
            padding: 40px;
            color: var(--text-light);
        }

        .spinner {
            width: 40px;
            height: 40px;
            border: 4px solid rgba(0, 0, 0, 0.1);
            border-left-color: var(--accent);
            border-radius: 50%;
            animation: spin 1s linear infinite;
            margin: 20px auto;
        }

        @keyframes spin {
            to {
                transform: rotate(360deg);
            }
        }

        .error {
            background: rgba(231, 76, 60, 0.1);
            border: 1px solid var(--error);
            color: var(--error);
            padding: 20px;
            border-radius: 4px;
            text-align: center;
            margin: 20px 0;
        }

        .reload-btn {
            background: var(--accent);
            color: white;
            border: none;
            padding: 8px 16px;
            border-radius: 4px;
            margin-top: 15px;
            cursor: pointer;
            transition: background 0.3s;
            font-size: 0.9rem;
        }

        .reload-btn:hover {
            background: var(--primary);
        }

        .stats {
            text-align: center;
            color: var(--text-light);
            font-size: 0.9rem;
            margin-bottom: 20px;
        }

        .page-info {
            display: flex;
            justify-content: center;
            align-items: center;
            gap: 15px;
            margin-top: 10px;
        }

        .page-input {
            width: 60px;
            padding: 8px;
            border: 1px solid var(--border);
            border-radius: 4px;
            text-align: center;
            font-size: 0.9rem;
        }

        .go-btn {
            background: var(--accent);
            color: white;
            border: none;
            padding: 8px 15px;
            border-radius: 4px;
            cursor: pointer;
            transition: background 0.3s;
        }

        .go-btn:hover {
            background: var(--primary);
        }

        @media (max-width: 600px) {
            body {
                padding: 20px 15px;
            }

            .article {
                padding: 20px;
            }

            .site-title {
                font-size: 1.5rem;
            }

            .article-title {
                font-size: 1.3rem;
            }

            .pagination {
                gap: 5px;
            }

            .pagination a {
                width: 32px;
                height: 32px;
                font-size: 0.85rem;
            }
        }
    </style>
</head>

<body>
    <header>
        <div class="logo">
            <i class="fas fa-blog"></i>
        </div>
        <h1 class="site-title">API动态博客</h1>
        <p class="site-subtitle">使用真实API请求数据 | 完整分页功能</p>
    </header>

    <div class="stats" id="stats-container">
        正在加载数据统计...
    </div>

    <main id="article-container">
        <div class="loading">
            <div class="spinner"></div>
            <p>正在加载文章数据...</p>
        </div>
    </main>

    <div class="pagination" id="pagination-container">
        <!-- 分页按钮将通过JavaScript动态生成 -->
    </div>

    <footer>
        <p>© 2023 动态博客 | JSONPlaceholder API实现</p>
        <p>每页显示5篇文章</p>
    </footer>

    <script>
        // 
        const HOST = document.location.origin;
        const API_ARTICLES = "/api/articles";
        const POSTS_PER_PAGE = 5;
        const TOTAL_POSTS = 100; // JSONPlaceholder有100篇文章
        const TOTAL_PAGES = Math.ceil(TOTAL_POSTS / POSTS_PER_PAGE);

        // 状态管理
        let currentPage = 1;

        // 分类数组（模拟分类数据）
        const categories = ['技术', '设计', '生活', '旅行', '编程', '科技', '文化', '教育'];

        // 格式化日期函数
        function formatDate(dateString) {
            const date = new Date(dateString);
            return `${date.getFullYear()}年${(date.getMonth() + 1).toString().padStart(2, '0')}月${date.getDate().toString().padStart(2, '0')}日`;
        }

        // 获取随机分类
        function getRandomCategory() {
            return categories[Math.floor(Math.random() * categories.length)];
        }

        // 获取随机日期（最近2年内）
        function getRandomDate() {
            const start = new Date(2022, 0, 1);
            const end = new Date();
            const randomDate = new Date(start.getTime() + Math.random() * (end.getTime() - start.getTime()));
            return formatDate(randomDate);
        }

        // 截取摘要文本
        function getExcerpt(text, maxLength = 120) {
            if (text.length <= maxLength) return text;
            return text.substring(0, maxLength) + '...';
        }

        // 从API获取文章数据
        async function fetchArticles(page = 1) {
            try {
                // 显示加载状态
                showLoading();

                // 构建API请求URL
                const url = `${HOST}${API_ARTICLES}?page=${page}&limit=${POSTS_PER_PAGE}`;

                // 发起API请求
                const response = await fetch(url);

                // 检查响应状态
                if (!response.ok) {
                    throw new Error(`网络响应错误: ${response.status}`);
                }

                // 解析JSON数据
                const data = await response.json();

                return data;
            } catch (error) {
                throw new Error(`获取文章失败: ${error.message}`);
            }
        }

        // 渲染文章列表
        function renderArticles(articles) {
            const container = document.getElementById('article-container');

            if (articles.length === 0) {
                container.innerHTML = `
                    <div class="loading">
                        <i class="fas fa-inbox" style="font-size: 3rem; margin-bottom: 20px; color: #ccc;"></i>
                        <p>没有找到相关文章</p>
                    </div>
                `;
                return;
            }

            let articlesHTML = '';

            articles.forEach(article => {
                articlesHTML += `
                    <article class="article">
                        <span class="article-date">${article.date}</span>
                        <h2 class="article-title"><a href="${article.readMoreLink}">${article.title}</a></h2>
                        <p class="article-excerpt">
                            ${article.excerpt}
                        </p>
                        <a href="${article.readMoreLink}" class="read-more">阅读全文 →</a>
                        <a href="#" class="category-tag">${article.category}</a>
                    </article>
                `;
            });

            container.innerHTML = articlesHTML;
        }

        // 渲染分页控件
        function renderPagination(totalPages, currentPage) {
            const container = document.getElementById('pagination-container');
            let paginationHTML = '';

            // 添加上一页按钮
            paginationHTML += `
                <a href="#" class="${currentPage === 1 ? 'disabled' : ''}" 
                   onclick="changePage(${currentPage - 1})" ${currentPage === 1 ? 'tabindex="-1"' : ''}>
                    <i class="fas fa-chevron-left"></i>
                </a>
            `;

            // 计算页码范围
            const maxVisiblePages = 5;
            let startPage = Math.max(1, currentPage - Math.floor(maxVisiblePages / 2));
            let endPage = startPage + maxVisiblePages - 1;

            if (endPage > totalPages) {
                endPage = totalPages;
                startPage = Math.max(1, endPage - maxVisiblePages + 1);
            }

            // 添加页码按钮
            for (let i = startPage; i <= endPage; i++) {
                paginationHTML += `
                    <a href="#" class="${i === currentPage ? 'active' : ''}" 
                       onclick="changePage(${i})">${i}</a>
                `;
            }

            // 添加下一页按钮
            paginationHTML += `
                <a href="#" class="${currentPage === totalPages ? 'disabled' : ''}" 
                   onclick="changePage(${currentPage + 1})" ${currentPage === totalPages ? 'tabindex="-1"' : ''}>
                    <i class="fas fa-chevron-right"></i>
                </a>
            `;

            // 添加跳转页面控件
            paginationHTML += `
                <div class="page-info">
                    <span>跳至:</span>
                    <input type="number" class="page-input" id="page-input" 
                           min="1" max="${totalPages}" value="${currentPage}">
                    <button class="go-btn" onclick="goToPage()">前往</button>
                </div>
            `;

            container.innerHTML = paginationHTML;
        }

        // 渲染统计数据
        function renderStats(stats) {
            const container = document.getElementById('stats-container');
            container.innerHTML = `
                <p>总文章数: ${stats.totalArticles} 篇 | 总页数: ${stats.totalPages} 页 | 当前页: ${currentPage}</p>
            `;
        }

        // 显示加载状态
        function showLoading() {
            const container = document.getElementById('article-container');
            container.innerHTML = `
                <div class="loading">
                    <div class="spinner"></div>
                    <p>正在加载文章数据...</p>
                </div>
            `;
        }

        // 显示错误信息
        function showError(message) {
            const container = document.getElementById('article-container');
            container.innerHTML = `
                <div class="error">
                    <i class="fas fa-exclamation-triangle"></i>
                    <p>${message}</p>
                    <button class="reload-btn" onclick="loadArticles()">重新加载</button>
                </div>
            `;
        }

        // 切换页面
        function changePage(page) {
            if (page < 1 || page > TOTAL_PAGES || page === currentPage) return;

            currentPage = page;
            loadArticles();

            // 滚动到页面顶部
            window.scrollTo({
                top: 0,
                behavior: 'smooth'
            });
        }

        // 跳转到指定页面
        function goToPage() {
            const input = document.getElementById('page-input');
            const page = parseInt(input.value);

            if (isNaN(page) || page < 1 || page > TOTAL_PAGES) {
                alert(`请输入1到${TOTAL_PAGES}之间的有效页码`);
                return;
            }

            changePage(page);
        }

        // 加载文章
        async function loadArticles() {
            try {
                // 获取文章数据
                const data = await fetchArticles(currentPage);

                const articles = data.articles;
                // 追加readMoreLink字段
                articles.forEach(article => {
                    article.readMoreLink = `${HOST}/static/article.html?id=${article.id}`;
                });
                renderArticles(articles);

                let totalPages = Math.ceil(data.total / POSTS_PER_PAGE);
                // 显示统计数据
                renderStats({ totalArticles: data.total, totalPages: totalPages })

                // 渲染分页控件
                renderPagination(totalPages, currentPage);
            } catch (error) {
                showError(error.message);

                // 出错时也渲染分页控件（保持导航功能）
                // renderPagination(totalPages, currentPage);
            }
        }

        // 初始化页面
        document.addEventListener('DOMContentLoaded', loadArticles);
    </script>
</body>

</html>